<template>
    <div class="my-map" ref="mapRef"></div>
</template>

<script>
import { loadGaodeMapScript } from '@/utils/utils'

function debounce(func, wait) {
    let timeout
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout)
            func.apply(this, args)
        }
        clearTimeout(timeout)
        timeout = setTimeout(later, wait)
    }
}
export default {
    props: {
        visible: { type: Boolean, default: false },
        title: { type: String, default: '地图' },
        initialPosition: {
            type: Object,
            default() {
                return { lng: 114.065953, lat: 22.547656 }
            }
        },
        chooseable: { type: Boolean, default: false }
    },
    data() {
        return {
            map: null,
            mapAuto: null,
            mapPlaceSearch: null,
            mapGeocoder: null,
            marker: null,
            infoWindow: null,
            form: {
                keyword: '',
                lng: '',
                lat: '',
                address: ''
            }
        }
    },
    computed: {
        // 地图配置
        mapConfig() {
            return this.$store.state.baseData.mapConfig
        },
        dialogVisible: {
            get() {
                return this.visible
            },
            set(val) {
                this.$emit('update:visible', val)
            }
        }
    },
    watch: {
        'form.keyword': {
            handler(nVal) {
                this.searchPlace()
            }
        }
    },
    mounted() {
        this.initMap()
    },
    methods: {
        handleConfirm() {
            if (!this.form.lng || !this.form.lat) {
                this.$message.warning('请先选择位置')
                return
            }
            let pos = {
                lng: this.form.lng,
                lat: this.form.lat
            }
            this.$emit('confirm', pos, this.form.address)
            this.dialogVisible = false
        },
        initMap() {
            window._AMapSecurityConfig = {
                securityJsCode: this.mapConfig.serverKey
            }
            let dom = this.$refs.mapRef
            let ak = this.mapConfig.jsKey
            loadGaodeMapScript(ak).then((res) => {
                if (this.map) {
                    return
                }
                var map = new AMap.Map(dom, {
                    zoom: 15,
                    plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder']
                }) // 创建Map实例
                this.map = map
                var point = new AMap.LngLat(this.initialPosition.lng, this.initialPosition.lat) // 创建点坐标
                map.setCenter(point)
                if (!this.infoWindow) {
                    this.infoWindow = new AMap.InfoWindow({
                        offset: new AMap.Pixel(0, -30)
                    })
                }
                map.on('click', (e) => {
                    if (!this.chooseable) return
                    let lng = e.lnglat.getLng()
                    let lat = e.lnglat.getLat()
                    // var text = `当前点击的坐标是[${lng}, ${lat}]`
                    // console.log(text)
                    this.form.lng = lng
                    this.form.lat = lat
                    // 创建点覆盖物
                    let marker = new AMap.Marker({
                        position: new AMap.LngLat(lng, lat)
                    })
                    if (this.marker) {
                        map.remove(this.marker)
                    }
                    map.add(marker)
                    this.marker = marker
                    marker.on('click', (e) => {
                        this.openInfoWindow(e.target.getPosition())
                    })
                    this.openInfoWindow(e.lnglat)
                })
                let centerMarker = new AMap.Marker({
                    position: new AMap.LngLat(this.initialPosition.lng, this.initialPosition.lat)
                })
                this.marker = centerMarker
                map.add(centerMarker)
                this.form.lng = this.initialPosition.lng
                this.form.lat = this.initialPosition.lat
                centerMarker.on('click', (e) => {
                    this.openInfoWindow([this.initialPosition.lng, this.initialPosition.lat])
                })
                setTimeout(() => {
                    AMap.Event.trigger(centerMarker, 'click')
                }, 200)

                AMap.plugin(['AMap.AutoComplete', 'AMap.Geocoder'], () => {
                    console.log('geocoder=======================')
                    // if (!this.mapAuto) {
                    //     this.mapAuto = new AMap.AutoComplete({
                    //         input: this.$refs.keywordRef.$el.querySelector('input')
                    //     })
                    //     // 当选中某条搜索记录时触发
                    //     this.mapAuto.on('select', this.selectAutoLocation)
                    // }
                    if (!this.mapGeocoder) {
                        let geocoder = new AMap.Geocoder()
                        this.mapGeocoder = geocoder
                    }
                })
            })
        },
        selectAutoLocation(location) {
            // console.log('自动搜索', location)
            this.form.keyword = location.poi.name
            // console.log('搜索', this.form.keyword)
            this.searchPlace()
        },
        searchPlace: debounce(function () {
            let _this = this
            if (!this.form.keyword) return
            AMap.plugin(['AMap.PlaceSearch'], () => {
                let placeSearch
                if (!_this.mapPlaceSearch) {
                    placeSearch = new AMap.PlaceSearch({
                        map: this.map, // 展现结果的地图实例
                        autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
                    })
                    // 为marker注册点击事件
                    AMap.Event.addListener(placeSearch, 'markerClick', function (e) {
                        // console.log(e.data.location) // 当前marker的经纬度信息
                        // console.log(e.data.location.lng + ',' + e.data.location.lat)
                        // console.log(e.data.address) // 获取当前marker的具体地址信息
                        // console.log(e.data) // 则是包含所有的marker数据
                        let markerLocation = e.data.location
                        _this.form.lng = markerLocation.lng
                        _this.form.lat = markerLocation.lat
                        _this.form.address = e.data.address
                    })
                } else {
                    placeSearch = _this.mapPlaceSearch
                }
                // 关键字查询
                placeSearch.search(this.form.keyword, function (status, result) {
                    console.log('搜索结果', result)
                })
            })
        }, 250),
        openInfoWindow(lnglat) {
            this.mapGeocoder.getAddress(lnglat, (status, result) => {
                if (status === 'complete' && result.regeocode) {
                    var address = result.regeocode.formattedAddress // 获取解析后的结果，即位置信息的地名
                    this.form.address = address
                    console.log(result.regeocode) // 显示位置信息的地名
                    this.infoWindow.setContent(`<b>地址：</b><p>${address}</p>`)
                    this.infoWindow.open(this.map, lnglat)
                }
            })
        },
        // 兼容百度地图组件中的方法
        handleClick(e) {
            const { lng, lat } = e.point
            let centerMarker = new AMap.Marker({
                position: new AMap.LngLat(lng, lat)
            })
            if (this.marker) {
                this.map.remove(this.marker)
            }
            this.marker = centerMarker
            this.map.add(centerMarker)
            centerMarker.on('click', (e) => {
                console.log('centerMarker click', e)
                this.openInfoWindow([lng, lat])
            })
            setTimeout(() => {
                AMap.Event.trigger(centerMarker, 'click')
            }, 200)
        }
    }
}
</script>

<style lang="less" scoped>
.my-map {
    width: 100%;
    height: 400px;
}
.map-search-form {
    display: flex;
    align-items: center;
}
.map-dialog-footer {
    text-align: center;
}
</style>
